﻿using ClientBackBone.EDDN;
using ShipsLog.Model;
using System;
using System.Configuration;
using System.ComponentModel;
using System.Windows.Forms;
using Verball;
using System.Linq;
using System.Collections.Specialized;
using System.IO;
using Microsoft.Win32;
using System.Diagnostics;

namespace ShipsLog
{
    public partial class Form1 : Form
    {
        private Verbliser verbliser;

        private ShipsModelControl modelControl;
        private bool SettingUp;

        public Form1()
        {
            string workingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +  @"/ShipsLogV1";
            if (!Directory.Exists(workingDirectory))
            {
                Directory.CreateDirectory(workingDirectory);
                File.Copy(@"Grammar.xml", Path.Combine(workingDirectory, "Grammar.xml"));
                File.Copy(@"Component.json1", Path.Combine(workingDirectory, "Component.json1"));
            }
            Directory.SetCurrentDirectory(workingDirectory);
            SetBrowserFeatureControl();

            InitializeComponent();
        }

        protected override void OnClosed(EventArgs e)
        {
            if (this.verbliser != null)
            {
                this.verbliser.Dispose();
            }

            if (this.modelControl != null)
            {
                this.modelControl.Dispose();
            }
            base.OnClosed(e);
        }

        private void SetBrowserFeatureControlKey(string feature, string appName, uint value)
        {
            using (var key = Registry.CurrentUser.CreateSubKey(
                String.Concat(@"Software\Microsoft\Internet Explorer\Main\FeatureControl\", feature),
                RegistryKeyPermissionCheck.ReadWriteSubTree))
            {
                key.SetValue(appName, (UInt32)value, RegistryValueKind.DWord);
            }
        }

        private UInt32 GetBrowserEmulationMode()
        {
            int browserVersion = 7;
            using (var ieKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer",
                RegistryKeyPermissionCheck.ReadSubTree,
                System.Security.AccessControl.RegistryRights.QueryValues))
            {
                var version = ieKey.GetValue("svcVersion");
                if (null == version)
                {
                    version = ieKey.GetValue("Version");
                    if (null == version)
                        throw new ApplicationException("Microsoft Internet Explorer is required!");
                }
                int.TryParse(version.ToString().Split('.')[0], out browserVersion);
            }

            UInt32 mode = 11000; // Internet Explorer 11. Webpages containing standards-based !DOCTYPE directives are displayed in IE11 Standards mode. Default value for Internet Explorer 11.
            switch (browserVersion)
            {
                case 7:
                    mode = 7000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode. Default value for applications hosting the WebBrowser Control.
                    break;
                case 8:
                    mode = 8000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode. Default value for Internet Explorer 8
                    break;
                case 9:
                    mode = 9000; // Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode. Default value for Internet Explorer 9.
                    break;
                case 10:
                    mode = 10000; // Internet Explorer 10. Webpages containing standards-based !DOCTYPE directives are displayed in IE10 mode. Default value for Internet Explorer 10.
                    break;
                default:
                    // use IE11 mode by default
                    break;
            }

            return mode;
        }

        private void SetBrowserFeatureControl()
        {
            // http://msdn.microsoft.com/en-us/library/ee330720(v=vs.85).aspx

            // FeatureControl settings are per-process
            var fileName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);

            // make the control is not running inside Visual Studio Designer
            if (String.Compare(fileName, "devenv.exe", true) == 0 || String.Compare(fileName, "XDesProc.exe", true) == 0)
                return;

            SetBrowserFeatureControlKey("FEATURE_BROWSER_EMULATION", fileName, GetBrowserEmulationMode()); // Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
            SetBrowserFeatureControlKey("FEATURE_AJAX_CONNECTIONEVENTS", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_MANAGE_SCRIPT_CIRCULAR_REFS", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_DOMSTORAGE ", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_GPU_RENDERING ", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_IVIEWOBJECTDRAW_DMLT9_WITH_GDI  ", fileName, 0);
            SetBrowserFeatureControlKey("FEATURE_DISABLE_LEGACY_COMPRESSION", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_LOCALMACHINE_LOCKDOWN", fileName, 0);
            SetBrowserFeatureControlKey("FEATURE_BLOCK_LMZ_OBJECT", fileName, 0);
            SetBrowserFeatureControlKey("FEATURE_BLOCK_LMZ_SCRIPT", fileName, 0);
            SetBrowserFeatureControlKey("FEATURE_DISABLE_NAVIGATION_SOUNDS", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_SCRIPTURL_MITIGATION", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_SPELLCHECKING", fileName, 0);
            SetBrowserFeatureControlKey("FEATURE_STATUS_BAR_THROTTLING", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_TABBED_BROWSING", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_VALIDATE_NAVIGATE_URL", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_WEBOC_DOCUMENT_ZOOM", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_WEBOC_POPUPMANAGEMENT", fileName, 0);
            SetBrowserFeatureControlKey("FEATURE_WEBOC_MOVESIZECHILD", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_ADDON_MANAGEMENT", fileName, 0);
            SetBrowserFeatureControlKey("FEATURE_WEBSOCKET", fileName, 1);
            SetBrowserFeatureControlKey("FEATURE_WINDOW_RESTRICTIONS ", fileName, 0);
            SetBrowserFeatureControlKey("FEATURE_XMLHTTP", fileName, 1);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var conf = ConfigurationManager.GetSection("comapnionApp") as NameValueCollection;
            this.modelControl = new ShipsModelControl();
            this.modelControl.UserNotify += this.LoginError;            
            this.modelControl.Init();  

            this.verbliser = new Verbliser(this.modelControl);

            this.propertyGrid1.SelectedObject = this.modelControl.Commander;
            this.propertyGrid1.ExpandAllGridItems();
            this.dataGridView2.AutoGenerateColumns = false;
            //this.dataGridView2.DataSource = new BindingList<Station>(this.modelControl.TradeData.Stations);
            this.propertyGrid1.DataBindings.Add(new Binding("SelectedObject", this.modelControl, "Commander", false, DataSourceUpdateMode.OnPropertyChanged));
            this.tabControl1.DataBindings.Add(new Binding("SelectedIndex", this.modelControl, "MenueMode", false, DataSourceUpdateMode.OnPropertyChanged));
            //this.dataGridView2.DataBindings.Add(new Binding("Items", this.modelControl.TradeData, "Stations", false, DataSourceUpdateMode.OnPropertyChanged));
            //this.dataGridView2.DataSource = this.modelControl.TradeData.Stations.ToArray();
            this.setStations();
            this.setRecomendations();
            this.setHistory();
            this.modelControl.PropertyChanged += modelControl_PropertyChanged;
            this.modelControl.TradeData.PropertyChanged += TradeData_PropertyChanged;
            this.SetImage();
            try
            {
                this.webBrowser1.Navigate(@"http:\\coriolis.io/outfit/" + this.modelControl.Ship.ToString());
            }
            catch (Exception ex)
            {
                this.LoginError(this, new EventArgs<string>(ex.Message));
            }
        }

        private void SetImage()
        {
            string imageFolder = this.modelControl.ImageFolder;
            foreach(var file in new DirectoryInfo(imageFolder).GetFiles("*.bmp"))
            {
                
                string pngName = file.FullName.Substring(0,file.FullName.Length -4) + ".png";
                if(!File.Exists(pngName))
                {
                    var bmp = System.Drawing.Bitmap.FromFile(file.FullName);        
                    bmp.Save(pngName, System.Drawing.Imaging.ImageFormat.Png);
                    File.SetCreationTime(pngName,file.CreationTime);
                }
            }

            var lastPngNameList = new DirectoryInfo(imageFolder).GetFiles("*.png").OrderByDescending(o => o.CreationTime);
            if (lastPngNameList != null && lastPngNameList.Count() > 0)
            {
                string lastPngName = lastPngNameList.First().FullName;
                var latestImage = System.Drawing.Bitmap.FromFile(lastPngName);
                this.pictureBox1.Image = latestImage;
                this.pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
                this.pictureBox1.Invalidate();
                textBox2.Text = lastPngName;
            }            
        }

        private void setHistory()
        {
            var serSet = this.chart1.Series;
            serSet.Clear();
            
            System.Windows.Forms.DataVisualization.Charting.Series deptSer = new System.Windows.Forms.DataVisualization.Charting.Series("Dept");
            deptSer.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.StackedArea;
            deptSer.Color = System.Drawing.Color.Violet;
            deptSer.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime;
            deptSer.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
            deptSer.ToolTip = "Amount Owed";

            System.Windows.Forms.DataVisualization.Charting.Series shipSer = new System.Windows.Forms.DataVisualization.Charting.Series("Ship");
            shipSer.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.StackedArea;
            shipSer.Color = System.Drawing.Color.Firebrick;
            shipSer.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime;
            shipSer.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;            
            shipSer.ToolTip = "Ship's Value";

            System.Windows.Forms.DataVisualization.Charting.Series cargoSer = new System.Windows.Forms.DataVisualization.Charting.Series("Cargo");
            cargoSer.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.StackedArea;
            cargoSer.Color = System.Drawing.Color.Yellow;
            cargoSer.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime;
            cargoSer.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
            cargoSer.ToolTip = "Cargo's Value";
            

            System.Windows.Forms.DataVisualization.Charting.Series cashSer = new System.Windows.Forms.DataVisualization.Charting.Series("Cash");
            cashSer.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.StackedArea;
            cashSer.Color = System.Drawing.Color.Orange;
            cashSer.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime;
            cashSer.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
            cashSer.ToolTip = "Cash";
            

            foreach(var commander in this.modelControl.History)
            {
                deptSer.Points.AddXY(commander.date,0 - commander.debt);
                shipSer.Points.AddXY(commander.date, commander.shipValue);
                cashSer.Points.AddXY(commander.date, commander.credits);
                cargoSer.Points.AddXY(commander.date, commander.cargoValue);
            }

            serSet.Add(deptSer);
            serSet.Add(shipSer);
            serSet.Add(cargoSer);
            serSet.Add(cashSer);
            this.chart1.Invalidate();

        }

        void TradeData_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "Stations": this.setStations();
                    break;
                case "Recommendations": this.setRecomendations();
                    break;

            }
        }

        private void LoginError(object sender, EventArgs<string> args)
        {
            if (args.Args == "companion.username")
            {
                GetEmail diag = new GetEmail();
                if (diag.ShowDialog(this) != System.Windows.Forms.DialogResult.OK)
                {
                    Environment.Exit(0);
                }
                
            }
            else if (args.Args == "companion.code")
            {
                GetCode diag = new GetCode();
                if (diag.ShowDialog(this) != System.Windows.Forms.DialogResult.OK)
                {
                    Environment.Exit(0);
                }
            }
        }

        private void setRecomendations()
        {
            this.dataGridView5.Rows.Clear();
            if (this.modelControl.TradeData.Recommendations != null)
            {
                foreach (var f in this.modelControl.TradeData.Recommendations)
                {
                    var row = new DataGridViewRow();
                    row.CreateCells(this.dataGridView5, new object[] { f.FromSystem, f.FromStation, f.Comodity, f.Amount, f.Cost, f.Value, f.ForProfit, f.ToSystem, f.ToStation, f.Recentcey });
                    this.dataGridView5.Rows.Add(row);
                }
            }

            this.dataGridView5.Invalidate();
        }

        void modelControl_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Commander")
            {
                this.verbliser.UpdateSucessfull();
                this.propertyGrid1.ExpandAllGridItems();
                this.setHistory();
            }
            if (e.PropertyName == "Commander")
            {
                this.webBrowser1.Navigate(@"http:\\coriolis.io/outfit/" + this.modelControl.Ship.ToString());
            }
            if (e.PropertyName == "ScreenGrab")
            {
                this.SetImage();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.verbliser = new Verbliser(this.modelControl);
        }

        private void statusToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void navigationToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void bindingSource1_DataMemberChanged(object sender, EventArgs e)
        {
        }

        private void bindingSource1_CurrentChanged(object sender, EventArgs e)
        {
        }

        private void bindingSource1_CurrentChanged_1(object sender, EventArgs e)
        {

        }

        private void dataGridView2_BindingContextChanged(object sender, EventArgs e)
        {
            if (this.modelControl != null)
            {
                this.setStations();
            }
        }

        private void setStations()
        {
            this.SettingUp = true;
            this.dataGridView2.Rows.Clear();
            this.dataGridView3.Rows.Clear();
            this.listBox1.Items.Clear();
            this.listBox2.Items.Clear();
            foreach (Station stat in this.modelControl.TradeData.Stations)
            {
                DataGridViewRow ro = new DataGridViewRow();
                
                ro.CreateCells(this.dataGridView2, new object[] { stat.SystemName, stat.StationName, stat.updated });
                ro.Tag = stat;
                this.dataGridView2.Rows.Add(ro);

                DataGridViewRow ro2 = new DataGridViewRow();
                ro2.CreateCells(this.dataGridView3, new object[] { stat.SystemName, stat.StationName, stat.updated });
                ro2.Tag = stat;
                this.dataGridView3.Rows.Add(ro2);

                this.listBox1.Items.Add(stat.SystemName + "~" + stat.StationName);
                this.listBox2.Items.Add(stat.SystemName + "~" + stat.StationName);
            }

            this.textBox1.Text = string.Empty;
            this.textBox1.Invalidate();
            this.listBox1.Invalidate();
            this.listBox2.Invalidate();
            this.dataGridView2.Invalidate();
            this.dataGridView3.Invalidate();
            textBox1.Text = string.Empty;
            this.SettingUp = false;
        }

        private void dataGridView2_SelectionChanged(object sender, EventArgs e)
        {
            this.dataGridView1.Rows.Clear();
            if (this.dataGridView2.SelectedRows != null && this.dataGridView2.SelectedRows.Count > 0)
            {
                foreach (Commodity comm in ((Station)this.dataGridView2.SelectedRows[0].Tag).Comodities.Values)
                {
                    DataGridViewRow ro = new DataGridViewRow();
                    ro.Tag = comm;
                    ro.CreateCells(this.dataGridView1, new object[] { comm.Name, comm.BuyPrice, comm.Supply, comm.SellPrice, comm.Demand });
                    this.dataGridView1.Rows.Add(ro);
                }
            }
        }

        private void dataGridView3_SelectionChanged(object sender, EventArgs e)
        {
            this.dataGridView4.Rows.Clear();
            if (this.dataGridView3.SelectedRows != null && this.dataGridView3.SelectedRows.Count > 0)
            {
                foreach (Commodity comm in ((Station)this.dataGridView3.SelectedRows[0].Tag).Comodities.Values)
                {
                    DataGridViewRow ro = new DataGridViewRow();
                    ro.Tag = comm;
                    ro.CreateCells(this.dataGridView4, new object[] { comm.Name, comm.BuyPrice, comm.Supply, comm.SellPrice, comm.Demand });
                    this.dataGridView4.Rows.Add(ro);
                }
            }
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

            this.CustomRecomend();

        }

        private void CustomRecomend()
        {
            if (listBox1.SelectedIndex >= 0 && listBox2.SelectedIndex >= 0 && listBox1.SelectedIndex != this.listBox2.SelectedIndex)
            {
                string[] from = listBox1.Items[this.listBox1.SelectedIndex].ToString().Split('~');
                string[] to = listBox2.Items[this.listBox2.SelectedIndex].ToString().Split('~');
                this.textBox1.Text = this.modelControl.GetSingleRecomendation(from, to);
                this.verbliser.Say(this.textBox1.Text);
            }
        }

        private void listBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.CustomRecomend();
        }

        private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
       
        }

        private void dataGridView2_CellClick(object sender, DataGridViewCellEventArgs e)
        {
          
        }

        private void dataGridView2_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            
        }

        private void dataGridView2_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (this.dataGridView2.Focused && e.KeyChar == ((Char)Keys.Delete))
            {
                var row = ((DataGridViewRow)this.dataGridView2.SelectedRows.GetEnumerator().Current);
                if (MessageBox.Show(this, string.Format("do you want to delete {0} station from {1}", row.Cells[1].Value.ToString(), row.Cells[0].Value.ToString())) == System.Windows.Forms.DialogResult.OK)
                {
                    this.modelControl.RemoveStation(row.Cells[0].Value.ToString(), row.Cells[1].Value.ToString());
                }                
            }
        }

        private void dataGridView2_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
        {
            if (!this.SettingUp)
            {
                
                var row = this.dataGridView2.Rows[e.RowIndex];
                if (MessageBox.Show(this, string.Format("do you want to delete {0} station from {1}", row.Cells[1].Value.ToString(), row.Cells[0].Value.ToString()),"DELETE STATION",MessageBoxButtons.OKCancel) == System.Windows.Forms.DialogResult.OK)
                {
                    this.modelControl.RemoveStation(row.Cells[0].Value.ToString(), row.Cells[1].Value.ToString());
                }
            }
        }

        private void showDebtToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.chart1.Series[0].Enabled = showDebtToolStripMenuItem.Checked;
            chart1.ChartAreas[0].RecalculateAxesScale();
        }

        private void showShipValueToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.chart1.Series[1].Enabled = showShipValueToolStripMenuItem.Checked;
            chart1.ChartAreas[0].RecalculateAxesScale();
        }

        private void showCargoValueToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.chart1.Series[2].Enabled = showCargoValueToolStripMenuItem.Checked;
            chart1.ChartAreas[0].RecalculateAxesScale();
        }

        private void showCashToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.chart1.Series[3].Enabled = showCashToolStripMenuItem.Checked;
            chart1.ChartAreas[0].RecalculateAxesScale();
        }

        private void chart1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                this.DataToggle.Show(this.chart1, e.Location);
            }
        }

        private void chart1_Click(object sender, EventArgs e)
        {

        }

        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void updateTimer_Tick(object sender, EventArgs e)
        {
            this.modelControl.Update(false);
        }

        private void updateButton_Click(object sender, EventArgs e)
        {
            this.modelControl.Update(true);
        }

        private void autoRefreshIntervaNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            autoUpdateProgressBar.Maximum = (int)autoRefreshIntervaNumericUpDown.Value - 1;

        }

        private void timerEnabledButton_Click(object sender, EventArgs e)
        {
            if (timerEnabledButton.Text == "Start")
            {
                autoUpdateProgressBar.Value = 0;
                progressTimer.Start();
                timerEnabledButton.Text = "Stop";
            }
            else
            {
                progressTimer.Stop();
                autoUpdateProgressBar.Value = 0;
                timerEnabledButton.Text = "Start";
            }
        }

        private void progressTimer_Tick(object sender, EventArgs e)
        {
            if(autoUpdateProgressBar.Value < autoUpdateProgressBar.Maximum)
            {
                autoUpdateProgressBar.Value++;
            }
            else
            {
                progressTimer.Stop();
                this.modelControl.Update(false);
                autoUpdateProgressBar.Value = 0;
                progressTimer.Start();
            }

        }

        private void exitButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            this.modelControl.ForgetMe();
        }
    }
}